﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Encryption
{
    public partial class PlayFairForm : Form
    {
        List<char> matrixList;
        char[][] matrix;
        char fullfillChar;
        Random rand = new Random();
        class matrixPoint
        {
            public int x;
            public int y;
            public matrixPoint(int x, int y )
            {
                this.x = x;
                this.y = y;
            }
        }
        Dictionary<char, matrixPoint> matrixDic;
        public PlayFairForm()
        {
            InitializeComponent();
        }
        private void PlayFairForm_Load(object sender, EventArgs e)
        {
            matrixList = new List<char>();
            matrix = new char[5][];
            for (int i = 0; i < 5;++i )
            {
                matrix[i] = new char[5];
            }
            matrixDic = new Dictionary<char,matrixPoint>() ;
        }

        private void createMatrixBtn_Click(object sender, EventArgs e)
        {
            string keyValu = KeyTex.Text;
            matrixList = new List<char>();
            matrixLab.Text = "";
            foreach(var c in keyValu)
            {
                char check = c;
                if(c=='i'|| c == 'j')//解决I J问题
                    check = 'i';
                if (matrixList.Contains(check) != true)
                {
                    matrixList.Add(check);
                    
                }
            }
            for (int i = 0; i < 26;++i )
            {
                char c = (char)('a' + i);
                if (c == 'i' || c == 'j')//解决I J问题
                    c = 'i';
                if (matrixList.Contains(c) != true)
                {
                    matrixList.Add(c);
                }
            }
            int k  = 0;
            for (int i = 0; i < 5; ++i)
            {
                for (int j = 0 ; j < 5 ;++j )
                {
                    matrix[i][j] = matrixList[k];
                    ++k;
                }
            }
            for (int i = 0; i < 5; ++i)
            {
                for (int j = 0; j < 5; ++j)
                {
                    if (matrix[i][j] == 'i')
                        matrixLab.Text += (matrix[i][j]+"/j" + " ");
                    else
                        matrixLab.Text += (matrix[i][j] + "   ");
                    matrixDic[matrix[i][j]] = new matrixPoint(i,j);
                }
                matrixLab.Text += "\n";
            }
        }

        private void EncodeBtn_Click(object sender, EventArgs e)
        {
            if (FillCharTex.Text == "")
            {
                MessageBox.Show("请输入正确的K值", "K值错误");
                return;
            }
            if (matrixLab.Text == "")
            {
                MessageBox.Show("请预先形成字母矩阵", "字母矩阵错误");
                return;
            }
            fullfillChar = (FillCharTex.Text.ToLower())[0];
            string clearString = encodeTex.Text.ToLower();
            string encodeString = "";
            char front_point ;
            char rear_point ;


            for (int i = 0 ; i <clearString.Length ; )
            {
                if ((i + 1) == clearString.Length)
                { 
                   //最后一个漏单了需要凑多一组
                    clearString += fullfillChar.ToString();
                }

                //分组
                front_point = clearString[i];
                rear_point = clearString[i+1];

                if(front_point == rear_point)
                {
                    if(front_point == fullfillChar)
                    {
                        rear_point = (char)((fullfillChar-'a'+1)%26+'a');
                    }
                    else
                    {
                        rear_point = fullfillChar;
                    }
                    ++i;
                }
                else
                    i+=2;


                if( matrixDic[front_point].x == matrixDic[rear_point].x)//同行
                {
                    encodeString += matrix[matrixDic[front_point].x][(matrixDic[front_point].y+1)%5].ToString();
                    encodeString += matrix[matrixDic[rear_point].x][(matrixDic[rear_point].y+1)%5].ToString();
                }
                else if(matrixDic[front_point].y == matrixDic[rear_point].y)//同列
                {
                    encodeString += matrix[(matrixDic[front_point].x+1)%5][matrixDic[front_point].y].ToString();
                    encodeString += matrix[(matrixDic[rear_point].x+1)%5][matrixDic[rear_point].y].ToString();
                }
                else//非同行同列
                {
                    encodeString += matrix[matrixDic[front_point].x][matrixDic[rear_point].y].ToString();
                    encodeString += matrix[matrixDic[rear_point].x][matrixDic[front_point].y].ToString();
                }
            }            
            decodeTex.Text = encodeString;

        }

        private void RandBtn_Click(object sender, EventArgs e)
        {
            FillCharTex.Text = ((char)('a'+rand.Next(0, 25))).ToString();
        }

        private void DecodeBtn_Click(object sender, EventArgs e)
        {
            if (matrixLab.Text == "")
            {
                MessageBox.Show("请预先形成字母矩阵", "字母矩阵错误");
                return;
            }
            if (encodeTex.Text.Length % 2 != 0)
            {
                MessageBox.Show("输入密文错误，长度应为偶数，请重新输入", "输入密文错误");
                return;
            }

            string encodeString = decodeTex.Text.ToLower();
            string clearString = "";
            char front_point ;
            char rear_point ;


            for (int i = 0; i < encodeString.Length; i+= 2)
            {
                //分组
                front_point = encodeString[i];
                rear_point = encodeString[i + 1];
               
                if( matrixDic[front_point].x == matrixDic[rear_point].x)//同行
                {
                    clearString += matrix[matrixDic[front_point].x][(matrixDic[front_point].y + 4) % 5].ToString();
                    clearString += matrix[matrixDic[rear_point].x][(matrixDic[rear_point].y + 4) % 5].ToString();
                }
                else if(matrixDic[front_point].y == matrixDic[rear_point].y)//同列
                {
                    clearString += matrix[(matrixDic[front_point].x + 4) % 5][matrixDic[front_point].y].ToString();
                    clearString += matrix[(matrixDic[rear_point].x + 4) % 5][matrixDic[rear_point].y].ToString();
                }
                else//非同行同列
                {
                    clearString += matrix[matrixDic[front_point].x][matrixDic[rear_point].y].ToString();
                    clearString += matrix[matrixDic[rear_point].x][matrixDic[front_point].y].ToString();
                }
            }
            encodeTex.Text = clearString;

        }


    }
}
